import datetime
import time
import math
import pandas as pd
from jqdatasdk import *
from jq_utils import *
from talib.abstract import MACD as macd_ta
import json
import os
import requests

sdk_auth()
wcf = os.path.expanduser("~/.config/wx.txt")
with open(wcf, "r") as f:
    wx_config = json.loads(f.readline().strip())


def macd_sign(macds, dts, code):
    last_aera = 0
    cur_aera = 0
    d_aeras = []
    g_aeras = []
    lstate = 'normal'
    sign = {}
    signs = []
    for index, d in enumerate(dts):
        sign = {}
        flag = -1
        if index > 2:
            m2 = macds[dts[index - 2]][2][code]
            m1 = macds[dts[index - 1]][2][code]
            m0 = macds[dts[index]][2][code]
            if m2 > m1 > m0:
               # bad
                flag = 1
            if m2 < m1 < m0:
               # good
                flag = 2
            if m2 < m1 and m1 > m0:
                flag = 3
            if m2 > m1 and m1 < m0:
                flag = 4

        cur_m  = macds[d][2][code]
        if cur_aera >= 0 and cur_m > 0:
            cur_aera += cur_m
        if cur_aera <= 0 and cur_m < 0:
            cur_aera += cur_m

        if cur_aera > 0 and flag == 3:
            sign['sign'] = 'buy smaller'

        if cur_aera < 0 and flag == 3:
            sign['sign'] = 'sell larger'
#         print(flag)

        last_same_aera = None
        if cur_aera > 0 and g_aeras:
            last_same_aera = g_aeras[-1]
        if cur_aera < 0 and d_aeras:
            last_same_aera =  d_aeras[-1]
#         print(d, last_same_aera, cur_aera, flag)
        state = 'normal'
        if last_same_aera:
            aera_large_flag = abs(cur_aera) > abs(last_same_aera)
            if cur_aera > 0:
                if aera_large_flag:
                    sign['bc'] = 'ok:not bc'
                else:
                    if flag == 3 or flag == 1:
                        if abs(cur_aera) * 2 < abs(last_same_aera):
                            sign['bc'] = 'warn:buy bc'
            else:
                if aera_large_flag:
                    state = 'danger:sell not bc'
                else:
                    if flag == 3 or flag == 2:
                        if abs(cur_aera) * 2 < abs(last_same_aera):
                            sign['bc'] = 'maybe good sign: bad maybe bc'
        if sign:
            signs.append(sign)
        #if state != lstate and state != 'normal':
        #    print(d, state)
        #    lstate = state
        if index > 0:
            last_m = macds[dts[index - 1]][2][code]
            if last_m < 0 and cur_m > 0:
                d_aeras.append(cur_aera)
                sign['sign'] = 'gold cross'
                last_aera = cur_aera
                cur_aera = cur_m
            if last_m > 0 and cur_m < 0:
                sign['sign'] = 'dead cross'
                g_aeras.append(cur_aera)
                last_aera = cur_aera
                cur_aera = cur_m
    return sign

def avg_percent(df, d):
    avg_percent = 0
    sum_m = 0
    sum_v = 0

    for index, row in df[df.date >= d].iterrows():
        sum_m += row.money
        sum_v += row.volume
        avg = sum_m / sum_v
        avg_percent = ((row.money/row.volume) / avg - 1) * 100
    return avg_percent

def monitor(end_dt, freq = "5m", count = 200):
    code = '000001.XSHG'
    df = get_bars(code, count, unit=freq,
         fields=['date','open','high','low','close', 'volume', 'money'],
              end_dt=end_dt, fq_ref_date=None,df=True)
    # print(df.tail(30))

    tday = end_dt.strftime("%Y-%m-%d")
    avg_lift = avg_percent(df, tday)
    mdf = pd.concat([df, macd_ta(df)], axis = 1)
    macds = {}
    dts = []
    for index,row in mdf.iterrows():
        if not math.isnan(row.macdhist):
            dts.append(row['date'])
            macds[row['date']] = [{code: row.macd}, {code: row.macdsignal}, {code: row.macdhist}]
    sign = macd_sign(macds, dts, code)
    if avg_lift > 5:
        sign["avg_lift"] = avg_lift
    if avg_lift < -5:
        sign["avg_lift"] = avg_lift

    if sign:
        sign['freq'] = freq
        sign["avg_lift"] = avg_lift
    return sign

def notify_sys(title, content):
    cmd = "notify-send '%s' '%s'" % (str(title), str(content))
    print(cmd)
    os.system(cmd)

def notify(msg):
    url = "http://wxpusher.zjiecode.com/api/send/message/?appToken={token}&content={msg}&uid={uid}"
    app_token = wx_config['token']
    uid = wx_config['uid']
    notify_sys("st", msg)

    res = requests.get(url.format(token=app_token, msg = msg, uid = uid))

def format_msg(d):
    return json.dumps(d)



def run_monitor():
    mdt = ["09:30","09:35","09:40","09:45","09:50","09:55","10:00","10:05","10:10","10:15","10:20","10:25","10:30","10:35","10:40","10:45","10:50","10:55","11:00","11:05","11:10","11:15","11:20","11:25","11:30","13:05","13:10","13:15","13:20","13:25","13:30","13:35","13:40","13:45","13:50","13:55","14:00","14:05","14:10","14:15","14:20","14:25","14:30","14:35","14:40","14:45","14:50","14:55","15:00"]
    mdt30 = ["09:30","10:00","10:30","11:00","11:30","13:00","13:30","14:00","14:30","14:50"]
    m = None
    m = None
    last = None
    last30 = None

    d = monitor(datetime.datetime.now(), "5m")
    print(d)
    # d30 = monitor("5m")
    # notify(format_msg(d))
    # notify(format_msg(d30))
    # notify_sys("st", msg)
    while 1:
        now = datetime.datetime.now()
        mt = now.strftime("%H:%M")
        if mt in mdt and mt != m:
            d = monitor(now, "5m")
            print(mt, "5m", d)
            if d != last:
                notify(format_msg(d))
                last = d
            if mt in mdt30 and mt != m:
                d30 = monitor(now, "30m")
                print(mt, "30m", d30)
                if d30 != last30:
                    notify(format_msg(d30))
                    last30 = d30
            m = mt

        time.sleep(1)


if __name__ == '__main__':
    run_monitor()

